home *** CD-ROM | disk | FTP | other *** search
/ L' Effet Pommier 3 / L'Effet Pommier - Volume 03.iso / Utils□□□ Divers 2 / ResCompare 2.6 folder / Documentation / Patch File Format < prev    next >
Text File  |  1996-02-19  |  20KB  |  407 lines

  1. Patch File Format
  2.  
  3. This document describes the format of the resources contained in version 5.0 of a ResCompare self╨applying patch.
  4.  
  5. To edit a patch file, use ResEdit with the supplied ╥Patch 5.0 templates╙ ResEdit document. Simply open this file in ResEdit, along with a patch file, to provide editing templates for the patch resources.
  6.  
  7. 'ZVER' resource
  8. A self╨applying patch contains patches for any number of versions of any number of files. There is a 'ZVER' resource for each file that is to be updated by the patch. The resource name is the prompt to be used when asking the user for this file.
  9.  
  10. The 'ZVER' resources are numbered starting at 128, in increments of 1.
  11.  
  12. The 'ZVER' resource contains some header information describing the file to be patched, followed by a list of valid versions. Here is the complete structure of the 'ZVER' resource:
  13.  
  14. /* Information maintained for each file version */
  15.  
  16. struct {
  17.     ZVerFlags      flags;
  18.     OSType         fdType, fdCreator;
  19.     MasterOption   masterOpt;
  20.     UpdateOption   updateOpt;
  21.     Size           finalRsrcForkSize;
  22.     unsigned long  finalCreationDate, finalModificationDate;
  23.     Str31          renameToName;
  24.     Str31          saveAsName;
  25.     short          numVersions;
  26.  
  27.     struct {
  28.         unsigned long  fromVersion;
  29.         unsigned long  toVersion;
  30.         short          zapListID;
  31.         long           totalMunges;
  32.     }            theZapRef[];
  33. } ZapVersion;
  34.  
  35. flags
  36. A bitmask of flags that can be OR-ed together, currently unused.
  37.  
  38. fdType, fdCreator
  39. These fields are the type and creator of the target file. Only files matching this criteria are listed in the GetFile dialog. You can remove the creator criteria by setting the creator to 0. To provide a more comprehensive list of types and creators, add a corresponding 'ZTC#' resource, which is described below.
  40.  
  41. masterOpt
  42. One of the following options, which define what is done with the master file after patching.
  43.  
  44. // Master file disposition
  45. enum {
  46.     kMasterLeaveOption, kMasterTrashOption,
  47.     kMasterDeleteOption,
  48.  
  49.     kMasterRenameMask = 0x80,
  50.     kMasterLeaveRenameOption = kMasterLeaveOption | kMasterRenameMask,
  51.     kMasterTrashRenameOption = kMasterTrashOption | kMasterRenameMask
  52.     // DeleteRename is nonsensical and illegal
  53. };
  54. typedef unsigned char MasterOption;
  55.  
  56. kMasterLeaveOption
  57. Do nothing to the master file; leave it alone. Invalid if combined with kUpdateReplaceOption, below.
  58.  
  59. kMasterTrashOption
  60. Move the master file to the Trash.
  61.  
  62. kMasterDeleteOption
  63. Delete the master file after patching.
  64.  
  65. kMasterRenameMask
  66. You can add this mask to either kMasterLeaveOption or kMasterTrashOption. It renames the master file to the name specified in renameToName, below.
  67.  
  68. updateOpt
  69. One of the following options, which define what is done with the update file after patching.
  70.  
  71. // Update file disposition
  72. enum {
  73.     kUpdateReplaceOption, kUpdateSaveAsOption, kUpdateExchangeOption
  74. };
  75. typedef unsigned char UpdateOption;
  76.  
  77. kUpdateReplaceOption
  78. Replace the master file with the update file. Invalid if combined with kMasterLeaveOption, above.
  79.  
  80. kUpdateSaveAsOption
  81. Prompt the user to save the update file, using the suggested name in saveAsName, below.
  82.  
  83. kUpdateExchangeOption
  84. Exchange the master file with the update file, preserving its file ID.
  85.  
  86. finalRsrcForkSize
  87. Final size in bytes of the file╒s resource fork after patching. This field is used to determine if disk space is available to perform the patch.
  88.  
  89. finalCreationDate, finalModificationDate
  90. Creation and modification date of the final patch in this version list. Used to set the update file╒s creation and modification date after patching.
  91.  
  92. renameToName
  93. If the master file╒s disposition uses kMasterRenameMask, it is renamed to this name. The renameToName can contain the substituters ^FILE, which is replaced with the target file╒s name, and ^VERS, which is replaced with the target file╒s version. The default renameToName is ╥^FILE ^VERS backup╙. If, after substitution, a file by this name already exists, a unique name is chosen by appending a number to the name.
  94.  
  95. saveAsName
  96. If the update file╒s disposition is kUpdateSaveAsOption, this field is used as the default name for the update file.
  97.  
  98. numVersions
  99. The number of version records to follow.
  100.  
  101. theZapRef[]
  102. A list of version records. This list is searched to locate a starting point for applying the patch. The version records use the following format:
  103.  
  104. fromVersion
  105. The 4╨byte version code this patch converts from.
  106.  
  107. toVersion
  108. The 4╨byte version code this patch converts to.
  109.  
  110. zapListID
  111. The resource ID of the 'ZAP#' resource for this patch.
  112.  
  113. totalMunges
  114. The total of all the numMunges fields in the corresponding 'ZAP#'. This info is used to calculate the goal for the status thermometer. 
  115.  
  116. 'ZFIL' resource
  117. This is an optional resource you can add to a patch once it╒s built to automatically identify a file╒s location without prompting the user. This is useful when the patch is for a control panel or extension, as the file may be in a folder locatable by FindFolder. The resource ID of the 'ZFIL' resource must match the 'ZVER' resource ID. The file must also have the same fdType and fdCreator as listed in the 'ZVER' or 'ZTC#' resource.
  118.  
  119. #define kAnyRegion    (-1)
  120.  
  121. // Will have the same ID as its corresponding ZVER
  122.  
  123.  
  124. typedef struct {
  125.     OSType     folderType;
  126.     short      numFileLocs;
  127.  
  128.     struct {
  129.         short      region;
  130.         Str31      name;
  131.     }          theFileLoc[];
  132. } ZapFileLocList;
  133.  
  134. folderType
  135. A four╨character type code recognized by FindFolder. The patch will search this folder on the system disk.
  136.  
  137. Set the folderType to a longword binary 0 (zero) to search for the target file by its full or partial pathname. Partial pathnames are resolved relative to the default volume and directory. The initial default volume and directory is the root directory of the system disk. To set folderType to zero with ResEdit, open an existing 'ZFIL' resource with the option key held down and change the first four bytes using the hex editor.
  138.  
  139. Set the folderType to a longword binary 1 to have the same effect as 0, but to reset the default volume and directory to its initial location first.
  140.  
  141. numFileLocs
  142. The number of possible file names to follow.
  143.  
  144. theFileLoc[]
  145. A list of file names. A list is used so multiple international spellings can be included. Each file name is accompanied by its region code, and the name corresponding to the current region of the system script is used.
  146.  
  147. region
  148. The region code that identifies this name, or the constant kAnyRegion (╨1) to match any region. Region codes are listed in Inside Macintosh, Volume VI, p. 14╨84, table 14╨10, in the <Packages.h> header file, and in ResEdit╒s ╥Country Code╙ pop╨up menu located in the 'vers' editor.
  149.  
  150. name
  151. The file name to look for, localized for this language.
  152.  
  153. The patch will scan the file loc list looking for a region code that matches the region of the system script, or for the wildcard value kAnyRegion (╨1).
  154.  
  155. If a file name cannot be found for the current region, the folder cannot be found, the requested file does not exist, or the file exists but its type and creator don╒t match, the patch will prompt the user for the file. If the patch was able to determine a file name, it places the name as dialog substitution parameter ╥^0╙, so you can use a prompt string of ╥Where is ^0?╙ to include the localized name in the prompt.
  156.  
  157. You can also provide a partial pathname, such as ╥:MyApp Folder:MyApp╙ to search a folder at the root level of the system disk named ╥MyApp Folder╙ for the ╥MyApp╙╩application.
  158.  
  159. 'ZTC#' resource
  160. This is an optional resource you can add to a patch once it╒s built to provide a comprehensive list of type/creator pairs that define a target file. You can use kTypeCreatorWildcard ('****') for either the type or the creator. The resource ID of the 'ZTC#' resource must match the 'ZVER' resource ID. The types and creators specified here override any type or creator given in the 'ZVER' resource.
  161.  
  162. #define kTypeCreatorWildcard    '****'
  163.  
  164. // Will have the same ID as its corresponding ZVER
  165.  
  166.  
  167. typedef struct {
  168.     short    numPairs;
  169.  
  170.     struct {
  171.         OSType   fdType, fdCreator;
  172.     }        pair[];
  173. } TypeCreatorList;
  174.  
  175. numPairs
  176. The number of type/creator pairs to follow.
  177.  
  178. fdType
  179. A four╨character file type code. The patch╒s GetFile dialog will only show files with this type and the creator specified below. Use '****' to match any type.
  180.  
  181. fdCreator
  182. A four╨character file creator code. The patch╒s GetFile dialog will only show files with this creator and the type specified above. Use '****' to match any creator.
  183.  
  184. 'ZAP#' resource
  185. The 'ZAP#' resource contains a list of all resources that need to be patched, for a given version transition of a given file. The 'ZVER' contains a list of 'ZAP#' resource IDs. The resource name of the 'ZAP#' will be the name of the master file from which the patch was created. This name is not used by the patch and is for reference purposes only. 'ZAP#' resources are numbered starting at 1000 and incremented by 1000.
  186.  
  187. The resource IDs of the 'ZAP ' resource that holds the munge data for patching each resource start with the 'ZAP#' and are incremented by 1. There is also a corresponding 'ZIS#' or 'ZIL#' resource with the same ID, based on the setting of the shortMunges flag.
  188.  
  189. struct {
  190.     short    numZaps;
  191.  
  192.     // Information maintained for each resource to be zapped
  193.     struct {
  194.         ZapFlags flags;
  195.         ResType  resType;
  196.         short    resID;
  197.  
  198.         short    newResAttrs;
  199.         Size     newResSize;
  200.  
  201.         // These fields are used to verify the resources
  202.         long     newResContentsChecksum;
  203.         short    resAttrs;
  204.         Size     resSize;
  205.         long     resContentsChecksum;
  206.         Str255   resName;
  207.     }       theZap[];
  208. } ZapList;
  209.  
  210. numZaps
  211. The number of zap records to follow. There is one for each resource to be patched.
  212.  
  213. flags
  214. A bitmask of flags that can be OR-ed together, with the following definitions:
  215.  
  216. /* Flags for use in the ZapRecord */
  217. #define zapStatusMaster        0x0100
  218. #define zapStatusUpdate        0x0200
  219.  
  220. enum {
  221.     shortMunges           = 0x00000001,
  222.     needNotVerify         = 0x00000002,
  223.     verifyFailed          = 0x00000004,
  224.     alwaysUpdate          = 0x00000008
  225.  
  226.     zapStatusError        = 0,
  227.     zapStatusSame         = zapStatusError,
  228.     zapStatusDeleted      = zapStatusMaster,
  229.     zapStatusAdded        = zapStatusUpdate,
  230.     zapStatusChanged      = ( zapStatusMaster | zapStatusUpdate ),
  231.  
  232.     // What parts of resource to skip during verification
  233.     dontVerifyAttrs       = 0x00010000,
  234.     dontVerifySize        = 0x00020000,
  235.     dontVerifyName        = 0x00040000,
  236.     dontVerifyContents    = 0x00080000,
  237.     dontVerifyNewContents    = 0x00100000
  238. } ZapFlags;
  239.  
  240. shortMunges
  241. If set, this flag indicates that both the master and update resource are less than 32K, and 16╨bit integers can be used for their offsets and lengths. Otherwise, 32╨bit integers must be used. When this flag is set, the zap instruction list is stored in a 'ZIS#' resource; otherwise, it is stored in a 'ZIL#' resource. Most resources are less than 32K, while most data forks of PowerPC applications are much larger.
  242.  
  243. needNotVerify
  244. If set, this flag indicates that, should resource verification fail, the patch application should perform the operation anyway in certain cases. If adding a resource that already exists, no change is made. If deleting a resource, the resource can be of any length if it exists. If changing a resource, no change is made.
  245.  
  246. verifyFailed
  247. This flag is used internally during the patching process and should always be set to 0 within the patch.
  248.  
  249. alwaysUpdate
  250. If set, this flag indicates that, should resource verification fail, the patch application should perform the operation anyway in all cases. If adding a resource that already exists, the entire resource is replaced. If deleting a resource, the resource can be of any length if it exists. If changing a resource, the resource╒s size is adjusted to its size in the master file and the patch is applied anyway.
  251.  
  252. The needNotVerify bit must be set for alwaysUpdate to take effect.
  253.  
  254. zapStatusMaster, zapStatusUpdate
  255. These flags indicate whether the target resource should appear in the master or update file, respectively. The various combinations of them are OR-ed together to indicate that the resource should be deleted, added, or changed.
  256.  
  257. dontVerifyAttrs, dontVerifySize, dontVerifyName, dontVerifyContents, dontVerifyNewContents
  258. If set, these flags indicate that the patcher should skip the check of the indicated parts of the master resource when determining whether the master file is a valid target. Resource existance is always verified, but can be controlled with the needNotVerify and alwaysUpdate bits.
  259.  
  260. resType, resID
  261. This is the resource type and ID of the resource to be patched.
  262.  
  263. newResAttrs
  264. These are the resource attributes to be applied to the update resource, or 0 if the resource is to be deleted.
  265.  
  266. newResSize
  267. This is the final size of the update resource, or 0 if the resource is to be deleted.
  268.  
  269. newResContentsChecksum
  270. This is a checksum of the data in the update resource, or 0 if the resource is to be deleted. After patching, the resource is checksummed and its value must match, unless the dontVerifyNewContents bit is set.
  271.  
  272. resAttrs
  273. These are the expected resource attributes of the master resource, or 0 if the resource is to be added. These attributes must match during resource verification, unless the dontVerifyAttrs bit is set.
  274.  
  275. The special resource attribute 0x0100 means this ╥resource╙ is really the data fork.
  276.  
  277. resSize
  278. This is the expected size of the master resource. If the resource is being added, this size will be 0. The sizes must match during resource verification, unless the dontVerifySize bit is set.
  279.  
  280. resContentsChecksum
  281. This is a checksum of the data in the master resource, or 0 if the resource is being added. During resource verification, the master resource is checksummed and its value must match, unless the dontVerifyContents bit is set.
  282.  
  283. resName
  284. This is the expected name of the master resource, or the empty string if the resource is to be added. The names must match during resource verification, unless the dontVerifyName bit is set.
  285.  
  286. Note that the final name of the update resource is stored as the resource name of its munge data ('ZAP ') resource (described below).
  287.  
  288. 'ZIL#' and 'ZIS#' resources
  289. The 'ZIL#' and 'ZIS#' resources contain a list of munges, or patch operations to be performed on a resource. Their formats are identical, except the 'ZIL#' uses 32╨bit offsets and lengths, while the 'ZIS#' uses 16╨bit offsets and lengths. 'ZIS#' is typically used, except for extremely large (>32K) resources. 'ZIL#' is typically used for the data fork.
  290.  
  291. The munges are divided into several lists: the additive munge list, the same-sized munge list, and the different-sized munge list. The different-sized munge list contains all the munges for which the master length is not the same as the update length. Note that a master length of 0 indicates data is being inserted, and an update length of 0 indicates data is being deleted.
  292.  
  293. A much more common occurrance is that the two lengths are the same. These munges are put into their own list, the same-sized munge list. This list is sorted into several groups, one for each unique common size. 
  294.  
  295. Of all the same-sized munges, those of length 1 are treated specially. For them, the signed difference between the update and the master byte is computed and if this difference occurs more than once, that munge is placed in the additive munge list. The delta value of the munge data is only stored once in the munge data.
  296.  
  297. Munges are applied in the order they╒re encountered in the munge instruction list.
  298.  
  299. /* 'ZIL#' */
  300. typedef struct {
  301.     long        masterOffset;            // Offset into master data at which to apply munge
  302. } AddLMunge, *AddLMungePtr;
  303.  
  304. typedef struct {
  305.     long        numAddMunges;            // Number of additive munges to follow
  306.     AddLMunge    theAddMunge[];            // List of additive munges
  307. } AddLMungeGroup, *AddLMungeGroupPtr;
  308.  
  309. typedef struct {
  310.     long        numAddMungeGroups;        // Number of additive munge groups
  311.     AddLMungeGroup    theAddMungeGroup[];    // List of additive munge groups
  312. } AddLMungeList, *AddLMungeListPtr;
  313.  
  314. typedef struct {
  315.     long        masterOffset;            // Offset into master data at which to apply munge
  316. } SSLMunge, *SSLMungePtr;
  317.  
  318. typedef struct {
  319.     long        commonLength;            // Common length for this group
  320.     long        numSSMunges;            // Number of same-sized munges to follow
  321.     SSLMunge    theSSMunge[];            // List of same-sized munges
  322. } SSLMungeGroup, *SSLMungeGroupPtr;
  323.  
  324. typedef struct {
  325.     long            numSSMungeGroups;    // Number of same-sized munge groups
  326.     SSLMungeGroup    theSSMungeGroup[];    // List of same-sized munge groups
  327. } SSLMungeList, *SSLMungeListPtr;
  328.  
  329. typedef struct {
  330.     long        masterOffset;            // Offset into master data at which to apply munge
  331.     long        masterLength;            // Length of master data to delete
  332.     long        updateLength;            // Length of update data to insert
  333. } DSLMunge, *DSLMungePtr;
  334.  
  335. typedef struct {
  336.     long            numDSMunges;        // Number of different-sized munges
  337.     DSLMunge        theDSMunge[];        // List of different-sized munges
  338. } DSLMungeList, *DSLMungeListPtr;
  339.  
  340. typedef struct {
  341.     AddLMungeList    theAddMungeList;    // Additive munge list
  342. //  SSLMungeList    theSSMungeList;        // Same-sized munge list
  343. //  DSLMungeList    theDSMungeList;        // Different-sized munge list
  344. } CmpLMungeList, *CmpLMungeListPtr, **CmpLMungeListHandle;
  345.  
  346.  
  347. /* 'ZIS#' */
  348. typedef struct {
  349.     short        masterOffset;            // Offset into master data at which to apply munge
  350. } AddSMunge, *AddSMungePtr;
  351.  
  352. typedef struct {
  353.     short           numAddMunges;             // Number of additive munges to follow
  354.     AddSMunge    theAddMunge[];            // List of additive munges
  355. } AddSMungeGroup, *AddSMungeGroupPtr;
  356.  
  357. typedef struct {
  358.     short                numAddMungeGroups;        // Number of additive munge groups
  359.     AddSMungeGroup    theAddMungeGroup[];    // List of additive munge groups
  360. } AddSMungeList, *AddSMungeListPtr;
  361.  
  362. typedef struct {
  363.     short        masterOffset;            // Offset into master data at which to apply munge
  364. } SSSMunge, *SSSMungePtr;
  365.  
  366. typedef struct {
  367.     short          commonLength;         // Common length for this group
  368.     short          numSSMunges;             // Number of same-sized munges to follow
  369.     SSSMunge    theSSMunge[];            // List of same-sized munges
  370. } SSSMungeGroup, *SSSMungeGroupPtr;
  371.  
  372. typedef struct {
  373.     short                  numSSMungeGroups;     // Number of same-sized munge groups
  374.     SSSMungeGroup    theSSMungeGroup[];    // List of same-sized munge groups
  375. } SSSMungeList, *SSSMungeListPtr;
  376.  
  377. typedef struct {
  378.     short        masterOffset;            // Offset into master data at which to apply munge
  379.     short        masterLength;            // Length of master data to delete
  380.     short        updateLength;            // Length of update data to insert
  381. } DSSMunge, *DSSMungePtr;
  382.  
  383. typedef struct {
  384.     short              numDSMunges;         // Number of different-sized munges
  385.     DSSMunge        theDSMunge[];        // List of different-sized munges
  386. } DSSMungeList, *DSSMungeListPtr;
  387.  
  388. typedef struct {
  389.     AddSMungeList    theAddMungeList;    // Additive munge list
  390. //  SSSMungeList     theSSMungeList;        // Same-sized munge list
  391. //  DSSMungeList     theDSMungeList;        // Different-sized munge list
  392. } CmpSMungeList, *CmpSMungeListPtr, **CmpSMungeListHandle;
  393.  
  394. 'ZAP ' resource
  395. The 'ZAP ' resource (note trailing space) contain the actualmunge data that╒s used for insert or replace patch operations. The data is arranged in the order specified by the munge instructions.
  396.  
  397. The updated resource gets its new resource name from the resource name of the 'ZAP ' resource. Every resource that is not being deleted gets a 'ZAP '/'ZIx#' resource pair, even if the only change is to the resource╒s attributes or name.
  398.  
  399. /* ZAP  resource--the munge data to insert/replace */
  400. #define ZapMungeType        'ZAP '
  401.  
  402. To contact me
  403. I hope you enjoy ResCompare. If you like it and find it useful, let me hear from you. If you have any suggestions, questions, or bug reports, send me e╨mail at hecht@vnet.net.
  404.  
  405. Clear as mud.
  406. ╤ Michael Hecht
  407.